home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 May: Tool Chest / Dev.CD May 98 TC.toast / Tool Chest / Development Kits / HyperCard Related / APDA HyperCard Toolkits / CD Audio Toolkit 1.0 / Source / CDSetTrackTitle.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-07  |  7.2 KB  |  288 lines  |  [TEXT/MPS ]

  1. /*
  2.     CDSetTrackTitle - An XFCN to set the title of the Track.
  3.     ©Apple Computer, Inc. 1988
  4.     All Rights Reserved.
  5.     
  6.     88/11/08    BL°B    First Version
  7.  
  8.     To compile and link this file using Macintosh Programmer's Workshop,
  9.  
  10.     C CDSetTrackTitle.c
  11.     link -sn Main=CDSetTrackTitle -sn STDIO=CDSetTrackTitle ∂
  12.          -sn INTENV=CDSetTrackTitle -rt XFCN=42 ∂
  13.          -m CDSetTrackTitle CDSetTrackTitle.c.o "{CLibraries}"CRuntime.o ∂
  14.          "{CLibraries}"StdCLib.o ∂
  15.          -o HyperCommands
  16.          
  17.     This link directive puts the XCMD in the file "HyperCommands".
  18.     Substitute the name of the stack you want it in.  To move XCMDs
  19.     between stacks, use ResEdit.  They can be in an individual stack,
  20.     the Home stack, the HyperCard application, or the System File.
  21.     
  22. */
  23.  
  24. #include <cd.h>
  25. #include <ToolUtils.h>
  26.  
  27. /* prototype definitions for functions */
  28. OSErr    ReadQ(short, short *, short *, short *, short *);
  29. OSErr    GetTrackTitle(unsigned long, short, StringPtr, long *);
  30.  
  31. /* **** WARNING:  DO NOT USE GLOBAL VARIABLES! **** */
  32.  
  33.  
  34. /************************************************************************
  35.  *
  36.  *  Function:        CDSetTrackTitle
  37.  *
  38.  *  Purpose:        set the title of this Track.
  39.  *
  40.  *  Returns:        0 if no error
  41.  *                    whatever driver/io errors we might have encountered
  42.  *                    otherwise.
  43.  *
  44.  *  Side Effects:
  45.  *
  46.  *  Description:    We need 1 parameter:  the new name for the Track.
  47.  *                    We'll accept a second optional parameter: the track
  48.  *                    number of the track we want to set.
  49.  *
  50.  *                    Get the ioRefNum that we got from previously calling
  51.  *                    CDOpen() by accessing the famous global.
  52.  *
  53.  *                    Look in the System Folder for the file
  54.  *                    "CD Remote Programs".  Open that file, look at the
  55.  *                    IndX resource to find out if we've got a matching
  56.  *                    index.  If we do, look up the STR# resource 
  57.  *                    referenced and modify that STR#'s first string to
  58.  *                    be the new string.  If we don't, create a new disc
  59.  *                    entry and then modify the new STR#'s first string
  60.  *                    to be the input string.
  61.  *
  62.  *                    Simple, really.
  63.  *
  64.  ************************************************************************/
  65. pascal void
  66. CDSetTrackTitle(paramPtr)
  67. XCmdBlockPtr    paramPtr;
  68. {
  69.     OSErr    result;
  70.     short    ioRefNum;
  71.     short    vRefNum;
  72.     short    resFile;
  73.     Handle    refHandle;
  74.     Handle    strHandle;
  75.     short    strListID;
  76.     unsigned long    discID;
  77.     short    numberOfTracks;
  78.     Str255    title;
  79.     Str255    newTitle;
  80.     Str31    returnString;
  81.     short    trackToFind;
  82.     short    minute, second, block;
  83.     Str31    fileName;
  84.     long    titleOffset;
  85.     
  86.     strcpy(title, "\p");
  87.     titleOffset = 2L;    /* point past word count in STR# */
  88.  
  89.     /* Must be 1 or 2 parameters */
  90.     if ((paramPtr->paramCount) != 1)
  91.     {
  92.         if ((paramPtr->paramCount) != 2)
  93.         {
  94.             /* Report error in parameters by returning -1 */
  95.             NumToStr(paramPtr, (long) -1, &returnString);
  96.             paramPtr->returnValue = PasToZero(paramPtr, (StringPtr) &returnString);
  97.             return;
  98.         }
  99.     }
  100.     /* check that size of input parameter is less than 255 chars */
  101.     if (strlen(*(paramPtr->params[0])) > 255)
  102.     {
  103.         /* Report error in parameters by returning -1 */
  104.         NumToStr(paramPtr, (long) -1, &returnString);
  105.         paramPtr->returnValue = PasToZero(paramPtr, (StringPtr) &returnString);
  106.         return;
  107.     }
  108.     
  109.     /* Get the global ioRefNum, vRefNum pair and split them out. */
  110.     refHandle = GetGlobal(paramPtr, GLOBALNAME);
  111.     ioRefNum = atoi(*(refHandle));
  112.     DisposHandle(refHandle);
  113.     vRefNum = ioRefNum >> 16;
  114.     ioRefNum &= 0xFFFF;
  115.  
  116.     result = noErr;
  117.     
  118.     /* 1st (possibly only) parameter is a Track title string  */
  119.     HandleToPString(paramPtr->params[0], (Ptr)newTitle);
  120.  
  121.     /* if we have a 2nd parameter, it's the track to set */
  122.     if (paramPtr->paramCount == 2)
  123.         trackToFind = atoi(*(paramPtr->params[1]));
  124.     else
  125.         result = ReadQ(ioRefNum, &trackToFind, &minute, &second, &block);
  126.  
  127.     GetIndString(fileName, STR_ID, DRIVENAME);
  128.     if (fileName == (Str31)0)
  129.         result = ResError();
  130.  
  131.     if (result == noErr)
  132.     {
  133.         resFile = OpenSystemResFile(fileName);
  134.         if (resFile == -1)
  135.             result = ResError();
  136.     }
  137.     
  138.     if (result == noErr)
  139.         result = IDDisc(ioRefNum, &discID);
  140.     
  141.     if (result == noErr)
  142.         result = GetNumberTracks(ioRefNum, &numberOfTracks);
  143.         
  144.     if (result == noErr)
  145.         if (FindIndex(discID, &strListID) == false)
  146.             result = AddDisc(discID, numberOfTracks);
  147.     
  148.     if (result == noErr)
  149.         if (FindIndex(discID, &strListID) == false)
  150.             result = fnfErr;
  151.         /* something's badly wrong at this point */
  152.         /* we've failed to create a valid program entry */
  153.         /* and we're hosed */
  154.     
  155.     if (result == noErr)
  156.         result = GetTrackTitle(strListID, trackToFind, title, &titleOffset);
  157.  
  158.     if (result == noErr)
  159.     {
  160.         strHandle = Get1Resource('STR#', strListID);
  161.         if (strHandle == nil)
  162.             result = ResError();
  163.     }
  164.     
  165.     if (result == noErr)
  166.         Munger(strHandle, titleOffset, title, title[0]+1, newTitle, newTitle[0]+1);
  167.     
  168.     if (result == noErr)
  169.     {
  170.         ChangedResource(strHandle);
  171.         result = ResError();
  172.     }
  173.     if (result == noErr)
  174.     {
  175.         WriteResource(strHandle);
  176.         result = ResError();
  177.     }
  178.     
  179.     CloseResFile(resFile);
  180.  
  181.     /* Convert result to string & return it */
  182.     NumToStr(paramPtr, (long) result, &returnString);
  183.     paramPtr->returnValue = PasToZero(paramPtr, (StringPtr) &returnString);
  184. }
  185.  
  186.  
  187.  
  188. /************************************************************************
  189.  *
  190.  *  Function:        ReadQ
  191.  *
  192.  *  Purpose:        return current Q subcode address data
  193.  *
  194.  *  Returns:        OSErr.  Probably either
  195.  *                        noErr        everything's hunky-dory!
  196.  *                        paramErr    you messed up the call somehow.
  197.  *
  198.  *  Side Effects:    none
  199.  *
  200.  *  Description:    Simply call the driver.  Return track number and
  201.  *                    absolute minute, second, block.
  202.  *
  203.  ************************************************************************/
  204. OSErr
  205. ReadQ(refNum, trackNo, minute, second, block)
  206. short    refNum;
  207. short    *trackNo;
  208. short    *minute;
  209. short    *second;
  210. short    *block;
  211. {
  212.     CDParam    myPB;
  213.     OSErr    result;
  214.     
  215.     myPB.ioCompletion = 0;
  216.     myPB.ioNamePtr = (char *) 0;
  217.     myPB.ioVRefNum = 1;
  218.     myPB.ioCRefNum = refNum;
  219.     myPB.csCode = READQ;
  220.     
  221.     result = PBControl(&myPB, false);
  222.     
  223.     if (result == noErr)
  224.     {
  225.         *trackNo = (short) BCD2DECIMAL(myPB.csParam[1]);
  226.         *minute = (short) BCD2DECIMAL(myPB.csParam[6]);
  227.         *second = (short) BCD2DECIMAL(myPB.csParam[7]);
  228.         *block = (short) BCD2DECIMAL(myPB.csParam[8]);
  229.     }
  230.     return result;
  231. }
  232.  
  233.  
  234.  
  235. /************************************************************************
  236.  *
  237.  *  Function:        GetTrackTitle
  238.  *
  239.  *  Purpose:        get the track title
  240.  *
  241.  *  Returns:        OSErr
  242.  *                    normally noErr.  If I can't get a resource, I'll
  243.  *                    return whatever ResError tells me.
  244.  *
  245.  *  Side Effects:    fills in title and offset
  246.  *
  247.  *  Description:    loop through the CD Remote Programs PROG and STR# 
  248.  *                    resources, trying to match the track number.
  249.  *
  250.  ************************************************************************/
  251. OSErr
  252. GetTrackTitle(rsrcID, trackNo, title, offset)
  253. unsigned long    rsrcID;
  254. short            trackNo;
  255. StringPtr        title;
  256. long            *offset;
  257. {
  258.     Handle    progHandle;
  259.     short    *prog;
  260.     short    limit;
  261.     short    realTrackNo;
  262.     OSErr    result;
  263.     
  264.     result = noErr;
  265.     
  266.     progHandle = Get1Resource('ProG', rsrcID);
  267.     if (progHandle == nil)
  268.         result = ResError();
  269.     if (result == noErr)
  270.     {
  271.         prog = (short *) *progHandle;
  272.         limit = prog[0];
  273.         GetIndString(title, rsrcID, 1);
  274.         for (realTrackNo = 1; realTrackNo <= limit; realTrackNo++)
  275.         {
  276.             *offset += title[0];
  277.             GetIndString(title, rsrcID, realTrackNo+1);
  278.             if (BCD2DECIMAL(prog[realTrackNo] & 0x00FF) == trackNo)
  279.                 break;
  280.         }
  281.     }
  282.     return result;
  283. }
  284.  
  285.  
  286. /* C routines for HyperCard callbacks */
  287. #include <XCmdGlue.inc.c>
  288.